# Command Tab module for CROSS

#########################################################################################
#
# Copyright (C) 2008  
# Authors: Aljosa Osep (aljosa.osep@gmail.com), Jernej Kranjec (jernej.kranjec@gmail.com)
# From Faculty of Electrical Engineering and Computer Science, Maribor, Slovenia
# Done at School of Technology, Seinajoki, Finland
# Under mentor Kimmo Salmenjoki (kimmo.salmenjoki@seamk.fi)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#########################################################################################

# ==================== imports ====================== #
import pygtk            # import pygtk library
pygtk.require('2.0')    # require version 2.o
import gtk 	        # import gtk

import os.path

import tabModule	# import abstract tab class	

############################
# commandTab class
############################
class commandTab(tabModule.abstractTab):
	# callbacks
	def set_table_text(self, widget, entry):			# retrieves data from Comminicator class and put it into label
		currentData = self.textbuffer.get_text(self.textbuffer.get_start_iter(),self.textbuffer.get_end_iter()) 
		inputData = self.communicator.retriveData()		# inputData <-- data from communicator(maschine answer)

		currentData = currentData + inputData
		self.textbuffer.set_text(currentData)			# put it into label

	def send_command(self, widget, entry):				# sends data from textentry to Communicator
		command = entry.child.get_text()			# get text from entry
		entry.append_text(command)				# append command to combo
		self.communicator.sendData(command+'\r\n')		# send command to communicator

	def clear_label(self, widget, label):				# clears label
		self.textbuffer.set_text("")				# set label text empty

	# methods
	def append_to_command(self, text):							# appends text to command label(console)
		self.textbuffer.set_text(self.textbuffer.get_text(self.textbuffer.get_start_iter(),self.textbuffer.get_end_iter()) + text)

	def clear_command(self):								# clear console
		self.textbuffer.set_text("")

	def open_box(self, widget):
		file_path = self.file_entry.get_text()						# retrieve path in file_entry txtbox
		if os.path.isfile(file_path) == True:						# if .txt file exsists
			self.clear_command()							# clear console
			inp = open(file_path, "r")						# open file
			for line in inp:							# read lines
				if line.startswith("}") == True:
					self.communicator.sendData(line)			# send data to communicator
					self.append_to_command(self.communicator.retriveData())	# and get response
			inp.close()									# close file, since we dont need it anymore

		else:											# otherwise, start file_open dialog
			open_file_box = gtk.FileChooserDialog("Select a command file", None, 		# create new open dialog with...
								gtk.FILE_CHOOSER_ACTION_OPEN,		
		                                          	(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, # ... 'cancel' and ...	
								gtk.STOCK_OPEN, gtk.RESPONSE_OK))	# ... 'ok' buttons

			open_file_box.set_default_response(gtk.RESPONSE_OK)				# default response: ok

			# applys file filters
			txtfilter = gtk.FileFilter()							# create new filter
			txtfilter.add_pattern("*.txt")							# for .txt files
			txtfilter.set_name("Text files")
			open_file_box.add_filter(txtfilter)						# add filter to dialog

			allfilter = gtk.FileFilter()							# create new filter
			allfilter.add_pattern("*")							# for all files
			allfilter.set_name("All files")
			open_file_box.add_filter(allfilter)						# append filter to dialog

			open_file_box.set_current_folder(self.file_entry.get_text())			# current folder is one in file_entry

			response = open_file_box.run()							# run dialog

			if response == gtk.RESPONSE_OK:							# check dialog response
				file_path = open_file_box.get_filename()				# OK - get path				
				self.clear_command()							# clear console
				inp = open(file_path, "r")						# open file
				for line in inp:							# for each line:
					if line.startswith("}") == True:
						self.communicator.sendData(line)			# send data to communicator
						self.append_to_command(self.communicator.retriveData())	# and get response
				inp.close()								# close file
			elif response == gtk.RESPONSE_CANCEL:						# response is "cancel"
				print 'closed, no files selected'

			open_file_box.destroy()								# destroy open dialog

	
	# initialisation
	def __init__(self, communicator):
		self.communicator = communicator					# sets communicator

		self.init_frame()							# init frame
		self.init_table(2, 3)							# init table

		#define title label
		label = gtk.Label()							# create title label
		self.table.attach(label, 0, 2, 0, 1, gtk.SHRINK, gtk.SHRINK) 		# attach it to table
		label.set_markup("<b>Enter a command to execute:</b>")			# sets title to label
		label.show()								# shows label

		# define combo entry
#		liststore = gtk.ListStore(str)
		entry = gtk.combo_box_entry_new_text()					# new entry object
		entry.child.set_text("}")						# set initial text
		entry.child.set_editable(True)						# set it editable
		entry.child.set_activates_default(True)
		self.table.attach(entry, 0, 1, 1, 2, gtk.FILL, gtk.SHRINK)		# attach it to table
		entry.child.set_flags(gtk.CAN_FOCUS)					# entry able to have focus
		entry.child.grab_focus()						# grab focus
		entry.show()								# show entry

		self.sw = gtk.ScrolledWindow()						# create scrolled window
		self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)		# set automatic policy
		self.label = gtk.TextView()						# create text view
		self.label.set_editable(False)						# it should not be editable, its just a console
		self.textbuffer = self.label.get_buffer()				# textbuffer for texview
		self.sw.add(self.label)							# add textview to scroller
		self.table.attach(self.sw, 0, 1, 2, 3,)					# attach grame to table
		self.sw.show()								# show scrolled window
		self.label.show()							# and show textview


		#define clear button		
		button = gtk.Button(stock=gtk.STOCK_CLEAR)				# create quit button
		button.connect("clicked", self.clear_label, self.label)			# connect event
		self.table.attach(button, 1, 2, 2, 3, gtk.SHRINK, gtk.SHRINK, 6, 0) 	# attach to table
		button.show()								# show button

		#define send button
		button = gtk.Button(stock=gtk.STOCK_APPLY)				# create send button
		button.connect("clicked", self.send_command, entry)			# connect events, click
		button.connect("clicked", self.set_table_text, entry)			# connect events, click
		self.table.attach(button, 1, 2, 1, 2, gtk.SHRINK, gtk.SHRINK, 6, 0)	# attach button to table
		button.set_flags(gtk.CAN_FOCUS)						# button able to have focus
		button.grab_focus()
		button.set_flags(gtk.CAN_DEFAULT)					# button can be default after entry input	
		button.grab_default()							# make it default after entry input		
		button.show()

		######## open_file horizontal box
		hbox = gtk.HBox(False, 0)						# horizontal box, for file stuff packing
		self.table.attach(hbox, 0, 2, 3, 4, gtk.FILL, gtk.SHRINK, 0, 8)		# attach it to table

		######## file path entry
		self.file_entry = gtk.Entry()						# new entry object
		self.file_entry.set_editable(True)					# set it editable
		hbox.pack_start(self.file_entry, True, True, 0)
#		entry.child.set_activates_default(True)
		self.file_entry.set_flags(gtk.CAN_FOCUS)				# entry able to have focus
#		entry.child.grab_focus()						# grab focus
		self.file_entry.show()

	
		######## open file button
		button = gtk.Button(stock=gtk.STOCK_OPEN)				# open file button
		hbox.pack_start(button, False, True, 5)					# pack it to horizontal box
		button.connect("clicked", self.open_box)				# connect to open_box event
		button.show()								# show button

		hbox.show()
		self.show_table_frame()							# show table and frame






